}
-long do_set_callbacks(unsigned long event_selector,
- unsigned long event_address,
- unsigned long failsafe_selector,
- unsigned long failsafe_address)
-{
- struct exec_domain *d = current;
-
- if ( !VALID_CODESEL(event_selector) || !VALID_CODESEL(failsafe_selector) )
- return -EPERM;
-
- d->arch.event_selector = event_selector;
- d->arch.event_address = event_address;
- d->arch.failsafe_selector = failsafe_selector;
- d->arch.failsafe_address = failsafe_address;
-
- return 0;
-}
-
-
long do_fpu_taskswitch(void)
{
set_bit(EDF_GUEST_STTS, ¤t->ed_flags);
{
return set_fast_trap(current, idx);
}
+
+long do_set_callbacks(unsigned long event_selector,
+ unsigned long event_address,
+ unsigned long failsafe_selector,
+ unsigned long failsafe_address)
+{
+ struct exec_domain *d = current;
+
+ if ( !VALID_CODESEL(event_selector) || !VALID_CODESEL(failsafe_selector) )
+ return -EPERM;
+
+ d->arch.event_selector = event_selector;
+ d->arch.event_address = event_address;
+ d->arch.failsafe_selector = failsafe_selector;
+ d->arch.failsafe_address = failsafe_address;
+
+ return 0;
+}
OFFSET(EDOMAIN_processor, struct exec_domain, processor);
OFFSET(EDOMAIN_vcpu_info, struct exec_domain, vcpu_info);
- OFFSET(EDOMAIN_event_sel, struct exec_domain, arch.event_selector);
OFFSET(EDOMAIN_event_addr, struct exec_domain, arch.event_address);
- OFFSET(EDOMAIN_failsafe_sel, struct exec_domain, arch.failsafe_selector);
OFFSET(EDOMAIN_failsafe_addr, struct exec_domain, arch.failsafe_address);
+ OFFSET(EDOMAIN_syscall_addr, struct exec_domain, arch.syscall_address);
OFFSET(EDOMAIN_trap_bounce, struct exec_domain, arch.trap_bounce);
OFFSET(EDOMAIN_thread_flags, struct exec_domain, arch.flags);
OFFSET(EDOMAIN_kernel_sp, struct exec_domain, arch.kernel_sp);
movl $TRAP_syscall,4(%rsp)
SAVE_ALL
GET_CURRENT(%rbx)
- bts $_TF_kernel_mode,EDOMAIN_thread_flags(%rbx)
- jc hypercall
- swapgs
- movq %rbx,%rdi
- call SYMBOL_NAME(write_ptbase)
- jmp restore_all_guest
+ testb $TF_kernel_mode,EDOMAIN_thread_flags(%rbx)
+ jnz hypercall
+
+ leaq EDOMAIN_trap_bounce(%rbx),%rdx
+ movq EDOMAIN_syscall_addr(%rbx),%rax
+ movq %rax,TRAPBOUNCE_eip(%rdx)
+ movw $0,TRAPBOUNCE_flags(%rdx)
+ pushq restore_all_guest(%rip)
+ jmp create_bounce_frame
hypercall:
sti
return NULL;
}
+
+long do_set_callbacks(unsigned long event_address,
+ unsigned long failsafe_address,
+ unsigned long syscall_address)
+{
+ struct exec_domain *d = current;
+
+ d->arch.event_address = event_address;
+ d->arch.failsafe_address = failsafe_address;
+ d->arch.syscall_address = syscall_address;
+
+ return 0;
+}
* for segment registers %ds, %es, %fs and %gs:
* %ds, %es, %fs, %gs, %eip, %cs, %eflags [, %oldesp, %oldss]
*/
- unsigned long event_selector; /* entry CS */
+
+ unsigned long event_selector; /* entry CS (x86/32 only) */
unsigned long event_address; /* entry EIP */
- unsigned long failsafe_selector; /* entry CS */
+ unsigned long failsafe_selector; /* entry CS (x86/32 only) */
unsigned long failsafe_address; /* entry EIP */
+ unsigned long syscall_address; /* entry EIP (x86/64 only) */
+
/* Bounce information for propagating an exception to guest OS. */
struct trap_bounce trap_bounce;